package com.googlecode.publicholiday.repository.jdbc;

import com.googlecode.publicholiday.repository.MutablePublicHolidayRepository;
import com.googlecode.publicholiday.utils.SqlUtils;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JdbcPublicHolidayRepository extends JdbcImmutablePublicHolidayRepository implements MutablePublicHolidayRepository {

    private final static String DELETE_PUBLIC_HOLIDAY_SQL = "DELETE public_holiday WHERE country_code = ? AND holiday_date = ?";
    private final static String INSERT_PUBLIC_HOLIDAY_SQL = "INSERT INTO public_holiday ( country_code, holiday_date ) VALUES ( ?, ? )";

    private final static Logger LOG = LoggerFactory.getLogger(JdbcPublicHolidayRepository.class);

    public JdbcPublicHolidayRepository(DataSource dataSource) {
        super(dataSource);
    }

    @Override
    public boolean create(String countryCode, LocalDate holidayDate) {
        boolean inserted = find(countryCode, holidayDate) == null;
        if (inserted) {
            Connection connection = null;
            PreparedStatement statement = null;
            try {
                LOG.debug("Attempting to create a Public Holiday in: {} on: {}", countryCode, holidayDate);
                connection = getDataSource().getConnection();
                statement = connection.prepareStatement(getCreatePublicHolidaySqlStatement());
                statement.setString(1, countryCode);
                statement.setDate(2, new Date(holidayDate.toDate().getTime()));
                statement.execute();
                inserted = statement.getUpdateCount() == 1;
                connection.commit();
            } catch (SQLException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } finally {
                SqlUtils.close(statement);
                SqlUtils.close(connection);
            }
        } else {
            LOG.debug("Public Holiday already exists in: {} on: {}", countryCode, holidayDate);
        }
        return inserted;
    }

    protected String getCreatePublicHolidaySqlStatement() {
        return INSERT_PUBLIC_HOLIDAY_SQL;
    }

    @Override
    public boolean delete(String countryCode, LocalDate holidayDate) {
        Connection connection = null;
        PreparedStatement statement = null;
        boolean deleted = true;
        try {
            LOG.debug("Attempting to delete a Public Holiday in: {} on: {}", countryCode, holidayDate);
            connection = getDataSource().getConnection();
            statement = connection.prepareStatement(getDeletePublicHolidaySqlStatement());
            statement.setString(1, countryCode);
            statement.setDate(2, new Date(holidayDate.toDate().getTime()));
            statement.execute();
            deleted = statement.getUpdateCount() == 1;
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            SqlUtils.close(statement);
            SqlUtils.close(connection);
        }
        return deleted;
    }

    protected String getDeletePublicHolidaySqlStatement() {
        return DELETE_PUBLIC_HOLIDAY_SQL;
    }
}
